#include "BaseSqliteHelper.h"

#include <QCoreApplication>
#include <QDir>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QDebug>
#include <QThread>
#include <QDate>
#include <QTextStream>

BaseSqliteHelper::BaseSqliteHelper()
	:m_rw_lock(QReadWriteLock::Recursive)
{

}

void BaseSqliteHelper::createCheckDB(const QString& tableName)
{
	QDir dir;
	QString dbPath = QCoreApplication::applicationDirPath() + QDir::separator() + "Test_DB";
	dir.mkpath(dbPath);

	QString sqlTextPath = QCoreApplication::applicationDirPath() + QDir::separator() + "Test_DB" + QDir::separator() + "SqlText";
	dir.mkpath(sqlTextPath);

	m_TableName = tableName;

	Q_ASSERT(!m_TableName.isEmpty());

	QString tablename = m_TableName;

	QString createTableSql = "CREATE TABLE IF NOT EXISTS %1 ("
		"id INTEGER PRIMARY KEY AUTOINCREMENT, "
		"barcode TEXT, "
		"uid TEXT, "
		"date_time DATETIME, "
		"message TEXT, "
		"upload INTEGER DEFAULT 0 "
		")";

	QString createDatetimeIndexSql = "CREATE INDEX IF NOT EXISTS datetimeIndex ON %1(date_time)";
	QString createBarcodeIndexSql = "CREATE INDEX IF NOT EXISTS barcodeIndex ON %1(barcode)";
	QString createUploadIndexSql = "CREATE INDEX IF NOT EXISTS uploadIndex ON %1(upload)";
	QString createUidIndexSql = "CREATE INDEX IF NOT EXISTS uidIndex ON %1(uid)";

	QSqlDatabase data_db = getSqliteDatabase();

	QWriteLocker Locker(&m_rw_lock);
	QSqlQuery query(data_db);

	if (!query.exec(createTableSql.arg(tablename)))
	{
		qCritical() << "创建表失败：" << query.lastError().text();
	}

	if (!query.exec(createDatetimeIndexSql.arg(tablename)))
	{
		qCritical() << "创建索引失败：" << query.lastError().text();
	}
	if (!query.exec(createBarcodeIndexSql.arg(tablename)))
	{
		qCritical() << "创建索引失败：" << query.lastError().text();
	}
	if (!query.exec(createUploadIndexSql.arg(tablename)))
	{
		qCritical() << "创建索引失败：" << query.lastError().text();
	}
	if (!query.exec(createUidIndexSql.arg(tablename)))
	{
		qCritical() << "创建索引失败：" << query.lastError().text();
	}

	data_db.close();
}

QString BaseSqliteHelper::getTableName()
{
	return m_TableName;
}

bool BaseSqliteHelper::insertData(QSharedPointer<BasicDetectionDefine> data)
{
	if (data == NULL)
		return false;

	Q_ASSERT(!m_TableName.isEmpty());

	QString sqlCmd = QString("insert into %1(uid,barcode,message,date_time,upload) \
            values('%2', '%3','%4','%5', '%6')")
		.arg(m_TableName)
		.arg(data->uid)
		.arg(data->barcode)
		.arg(data->message)
		.arg(data->date_time)
		.arg(0);

	QSqlDatabase data_db = getSqliteDatabase();

	QWriteLocker Locker(&m_rw_lock);
	QSqlQuery query = QSqlQuery(data_db);
	if (!query.exec(sqlCmd))
	{
		qCritical() << "插入失败：" << query.lastError().text() << " : " << sqlCmd;

	}
	data_db.close();

	return true;
}



bool BaseSqliteHelper::updateData(QSharedPointer<BasicDetectionDefine> data)
{
	if (data == NULL)
		return false;

	Q_ASSERT(!m_TableName.isEmpty());

	QString sqlCmd = QString("update %1 set upload = %2,message='%3' where barcode = '%4' and uid = '%5'")
		.arg(m_TableName)
		.arg(data->upload)
		.arg(data->message)
		.arg(data->barcode)
		.arg(data->uid);

	QSqlDatabase data_db = getSqliteDatabase();

	QWriteLocker Locker(&m_rw_lock);
	QSqlQuery query = QSqlQuery(data_db);
	if (!query.exec(sqlCmd))
	{
		qCritical() << "更新失败：" << query.lastError().text() << " : " << sqlCmd;
	}
	data_db.close();

	return true;
}

QSharedPointer<BasicDetectionDefine> BaseSqliteHelper::getNewestData(const QString& barcode)
{
	QSharedPointer<BasicDetectionDefine> data = NULL;

	Q_ASSERT(!m_TableName.isEmpty());

	QVector<QSqlRecord> last_query_result;
	QString sqlCmd = QString("select * from '%1' where barcode = '%2' order by id desc limit 1").arg(m_TableName).arg(barcode);

	QSqlDatabase data_db = getSqliteDatabase(m_TableName);

	QReadLocker Locker(&m_rw_lock);
	QSqlQuery query = QSqlQuery(data_db);
	if (query.exec(sqlCmd))
	{
		while (query.next())
		{
			last_query_result.push_back(query.record());
		}
	}
	else
	{
		qCritical() << "获取数据失败：" << query.lastError().text() << " : " << sqlCmd;
	}

	foreach(const QSqlRecord & record, last_query_result)
	{
		data = ConvertTodBasc(record);
		break;
	}

	data_db.close();

	return data;
}

QSharedPointer<BasicDetectionDefine> BaseSqliteHelper::ConvertTodBasc(const QSqlRecord& record)
{
	QSharedPointer<BasicDetectionDefine> data = QSharedPointer<BasicDetectionDefine>::create();

	data->id = record.value(record.indexOf("id")).toInt();
	data->uid = record.value(record.indexOf("uid")).toString();
	data->barcode = record.value(record.indexOf("barcode")).toString();
	data->upload = record.value(record.indexOf("upload")).toInt();
	data->message = record.value(record.indexOf("message")).toString();
	data->date_time = record.value(record.indexOf("date_time")).toString();

	return data;
}

QSqlDatabase BaseSqliteHelper::getSqliteDatabase(const QString& tableName)
{
	QString db_name = tableName;
	if (db_name.isEmpty())
		db_name = m_TableName;

	QString dbPath = QCoreApplication::applicationDirPath() + QDir::separator() + "Test_DB";

	QString sqlite_db = dbPath + QDir::separator() + db_name + ".db";

	//不同线程 不同的QSqlDatabase
	//相同线程  用一个。。如果是协程的话应该会有问题。。。。 一个关闭 另外一个正在使用。。。!!!!!!!!
	Qt::HANDLE threadId = QThread::currentThreadId();
	QString connect_name = QString::number(reinterpret_cast<quintptr>(threadId)) + "_" + db_name;

	QSqlDatabase db;
	if (QSqlDatabase::contains(connect_name))
	{
		db = QSqlDatabase::database(connect_name);
	}
	else {
		db = QSqlDatabase::addDatabase("QSQLITE", connect_name);
		db.setDatabaseName(sqlite_db);
	}

	if (!db.isOpen())
		db.open();
	return db;
}
